#include "maindialog.h"
#include "ui_maindialog.h"


#include <QIODevice>
#include <QMessageBox>
#include <QSerialPortInfo>
#include <QDebug>

mainDialog::mainDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::mainDialog)
{
    ui->setupUi(this);

    ui->sliderLED1->setRange(0, 1000);
    ui->sliderServo->setRange(0, 360);

    memset(&devCmd, 0, sizeof(devCmd));  // 清空结构体

    devCmd.head = 0x5AA5;  // 设置前导
    devCmd.tail = 0x3CC3;  // 设置后导

    // 枚举系统中所有可用串口
    QList<QSerialPortInfo> allPorts = QSerialPortInfo::availablePorts();

    for(const QSerialPortInfo& sp : allPorts)
    {
        ui->comboUart->addItem(sp.portName());
    }
    // 列出常用波特率
    ui->combobps->addItem(QString::number(115200));
    ui->combobps->addItem(QString::number(9600));
    ui->combobps->addItem(QString::number(4800));

    m_sp = new QSerialPort(this);  // 创建一个串口对象

    // 连接 m_sp 这个对象的信号和当前窗口对象的收数据槽函数
    connect(m_sp, &QIODevice::readyRead, this, &mainDialog::recvData);
}

mainDialog::~mainDialog()
{
    delete ui;
}

void mainDialog::recvData()
{
    int i;
    static QByteArray prevData;  // 静态字节数组

    QByteArray curData = prevData + m_sp->readAll();

    //qDebug() << "------" << data << "------";

    // 只要有 \n 在里面，一条消息就会被切成两半
    QList<QByteArray> msgs = curData.split('\n');
    QList<QByteArray> p;

    for(i = 0; i < msgs.size() - 1; i ++)
    {
        qDebug() << msgs[i];

        // 每次提取一条完整的消息就进行一次处理
        p = msgs[i].split(':');

        if(p.size() != 2) continue;  // 如果 p 被 : 切割之后的长度不是 2，就退出本次循环
        // 蜂鸣器
        if(p[0] == "BEEP1")
        {
            if(p[1] == "0") ui->btnBeepCtl->setText("报警");
            else if(p[1] == "1") ui->btnBeepCtl->setText("静音");
        }
        // LED_A1
        if(p[0] == "LED_A1")
        {
            if(p[1] == "0") ui->btnLED2Ctl->setText("打开LED2");
            else if(p[1] == "1") ui->btnLED2Ctl->setText("关闭LED2");
        }
        // LED_C15
        if(p[0] == "LED_C15")
        {
            if(p[1] == "0") ui->btnLED3Ctl->setText("打开LED3");
            else if(p[1] == "1") ui->btnLED3Ctl->setText("关闭LED3");
        }
        // LED_C13
        if(p[0] == "LED_C13")
        {
            if(p[1] == "0") ui->btnLED4Ctl->setText("打开LED4");
            else if(p[1] == "1") ui->btnLED4Ctl->setText("关闭LED4");
        }
        // DHT11
        if(p[0] == "DHT11_1")
        {
            QList<QByteArray> th = p[1].split('_');
            ui->labeltemp->setText(QString(th[0] + "℃"));
            ui->labelhumi->setText(QString(th[1] + "%RH"));
        }
    }
    prevData = msgs[i];  // 更新数据
}


void mainDialog::on_btnOpen_clicked()
{
    if(ui->btnOpen->text() == "打开")  // 如果按钮文本显示打开
    {
        QString portName = ui->comboUart->currentText();
        int baud = ui->combobps->currentText().toUInt();
        qDebug() << baud;  // 打印当前串口的波特率

        m_sp->setPortName(portName);  // 设置串口号
        m_sp->setBaudRate(baud);  // 设置波特率
        m_sp->setDataBits(QSerialPort::Data8);  // 设置数据位为 8 位，QSerialPort::Data8 是枚举类型
        m_sp->setParity(QSerialPort::NoParity);  // 无校验
        m_sp->setStopBits(QSerialPort::OneStop);  //  停止位为 1 位

        // 万事俱备，打开串口
        if(!m_sp->open(QIODevice::ReadWrite))  // 打开失败
        {
            QMessageBox::critical(this, "君哥提示", "打开串口失败");
        }
        else
        {
            ui->btnOpen->setText("关闭");
        }
    }
    else
    {
        m_sp->close();  // 关闭串口
        ui->btnOpen->setText("打开");
    }
}

void mainDialog::on_btnBeepCtl_clicked()
{
    if(m_sp->isOpen())  // 判断串口是否打开
    {
        devCmd.devType = 2;  // 设备类型
        devCmd.devID = 1;  // 设备ID

        if(ui->btnBeepCtl->text() == "报警")
            devCmd.devCmd = 1;
        else if(ui->btnBeepCtl->text() == "静音")
            devCmd.devCmd = 0;

        m_sp->write((const char*)&devCmd, sizeof(devCmd));  // 发送

        //unsigned char cmd[12] = {0xA5, 0x5A, 2, 0, 1, 0, 1, 0, 0, 0, 0xC3, 0x3C};
        //m_sp->write((const char*)&cmd, sizeof(cmd));
    }
}

void mainDialog::on_btnLED2Ctl_clicked()
{
    if(m_sp->isOpen())  // 判断串口是否打开
    {
        devCmd.devType = 1;  // 设备类型
        devCmd.devID = 2;  // 设备ID

        if(ui->btnLED2Ctl->text() == "打开LED2")
            devCmd.devCmd = 1;
        else if(ui->btnLED2Ctl->text() == "关闭LED2")
            devCmd.devCmd = 0;

        m_sp->write((const char*)&devCmd, sizeof(devCmd));  // 发送
    }
}

void mainDialog::on_btnLED3Ctl_clicked()
{
    if(m_sp->isOpen())  // 判断串口是否打开
    {
        devCmd.devType = 1;  // 设备类型
        devCmd.devID = 3;  // 设备ID

        if(ui->btnLED3Ctl->text() == "打开LED3")
            devCmd.devCmd = 1;
        else if(ui->btnLED3Ctl->text() == "关闭LED3")
            devCmd.devCmd = 0;

        m_sp->write((const char*)&devCmd, sizeof(devCmd));  // 发送
    }
}

void mainDialog::on_btnLED4Ctl_clicked()
{
    if(m_sp->isOpen())  // 判断串口是否打开
    {
        devCmd.devType = 1;  // 设备类型
        devCmd.devID = 4;  // 设备ID

        if(ui->btnLED4Ctl->text() == "打开LED4")
            devCmd.devCmd = 1;
        else if(ui->btnLED4Ctl->text() == "关闭LED4")
            devCmd.devCmd = 0;

        m_sp->write((const char*)&devCmd, sizeof(devCmd));  // 发送
    }
}

void mainDialog::on_sliderLED1_valueChanged(int value)
{
    if(m_sp->isOpen())  // 判断串口是否打开
    {
        devCmd.devType = 1;  // 设备类型
        devCmd.devID = 1;  // 设备ID
        devCmd.devCmd = 1;  // 打开 LED1
        devCmd.devCmdArg = value;  // 滑块的值

        m_sp->write((const char*)&devCmd, sizeof(devCmd));  // 发送
    }
}

void mainDialog::on_sliderServo_valueChanged(int value)
{
    if(m_sp->isOpen())  // 判断串口是否打开
    {
        devCmd.devType = 4;  // 设备类型
        devCmd.devID = 1;  // 设备ID
        devCmd.devCmd = 1;  // 打开舵机
        devCmd.devCmdArg = value;  // 滑块的值

        m_sp->write((const char*)&devCmd, sizeof(devCmd));  // 发送
    }
}
